﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Samurai.Validation.Specs
{
    /// <summary>
    /// Provides BDD-style assertations for object references.
    /// </summary>
    public static class ObjectSpecificationExtensions
    {
        /// <summary>
        /// Verifies that the object reference is null.
        /// </summary>
        /// <param name="actual">The reference to verify.</param>
        public static void ShouldBeNull(this object actual)
        {
            Assert.IsNull(actual);
        }

        /// <summary>
        /// Verifies that the object reference is not null.
        /// </summary>
        /// <param name="actual">The reference to verify.</param>
        public static void ShouldNotBeNull(this object actual)
        {
            Assert.IsNotNull(actual);
        }

        /// <summary>
        /// Verifies that two objects are equal.
        /// </summary>
        /// <param name="actual">The actual object.</param>
        /// <param name="expected">The expected object.</param>
        public static void ShouldEqual(this object actual, object expected)
        {
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Verifies that two objects are not equal.
        /// </summary>
        /// <param name="actual">The actual object.</param>
        /// <param name="notExpected">The unexpected object.</param>
        public static void ShouldNotEqual(this object actual, object notExpected)
        {
            Assert.AreNotEqual(notExpected, actual);
        }

        /// <summary>
        /// Verifies that two objects are the same instance.
        /// </summary>
        /// <param name="actual">The actual object.</param>
        /// <param name="expected">The expected object.</param>
        public static void ShouldBeTheSameAs(this object actual, object expected)
        {

            Assert.AreSame(expected, actual);

        }

        /// <summary>
        /// Verifies that two objects are not the same instance.
        /// </summary>
        /// <param name="actual">The actual object.</param>
        /// <param name="notExpected">The unexpected object.</param>
        public static void ShouldNotBeTheSameAs(this object actual, object notExpected)
        {

            Assert.AreNotSame(notExpected, actual);

        }

        /// <summary>
        /// Verifies that an object is of a specific type.
        /// </summary>
        /// <param name="actual">The actual object.</param>
        /// <param name="expected">The expected type.</param>
        public static void Is(this object actual, Type expected)
        {

            Assert.IsInstanceOfType(actual, expected);

        }

        /// <summary>

        /// Verifies that an object is not a specific type.

        /// </summary>

        /// <param name="actual">The actual object.</param>

        /// <param name="expected">The unexpected typ.</param>
        public static void IsNot(this object actual, Type notExpected)
        {
            Assert.IsNotInstanceOfType(actual, notExpected);
        }
    }

    /// <summary>
    /// Provides BDD-style assertations for boolean values.
    /// </summary>
    public static class BooleanSpecificationExtensions
    {
        /// <summary>
        /// Verifies that the value is true.
        /// </summary>
        /// <param name="actual">if set to <c>true</c> [actual].</param>
        public static void ShouldBeTrue(this bool actual)
        {
            Assert.IsTrue(actual);
        }

        /// <summary>
        /// Verifies that the value is false.
        /// </summary>
        /// <param name="actual">if set to <c>true</c> [actual].</param>
        public static void ShouldBeFalse(this bool actual)
        {
            Assert.IsFalse(actual);
        }
    }
}
